<template>
  <div class="dynamic-form-container">
    <ElForm 
      ref="fieldFormRef" 
      :model="formData" 
      :rules="fieldRules" 
      label-width="105px"
      class="dynamic-form"
    >
      <template v-for="(row, rowIndex) in computedRows" :key="rowIndex">
        <ElRow :gutter="20">
          <template v-for="col in row" :key="col.name">
            <ElCol 
              :span="col.span || 12"
              v-if="shouldShowField(col)"
            >
              <ElFormItem 
                :label="col.label" 
                :prop="col.name"
                :rules="col.rules"
              >
                <!-- Input / Textarea / Password -->
				<InputField
					v-if="['Input', 'Textarea', 'Password'].includes(col.controlType)" 
					:field="col"
					:data="formData"
				/>
				
				<!-- Select -->
				<SelectField
					v-else-if="['Select'].includes(col.controlType)" 
					:field="col"
					:data="formData"
					:fetchOptions="props.fetchDatas[col.name]"
					:option="props.options[col.name]"
				/>
				
				<!-- TreeSelect -->
				<TreeSelectField
					v-else-if="['TreeSelect'].includes(col.controlType)" 
					:field="col"
					:data="formData"
					:fetchOptions="props.fetchDatas[col.name]"
					:option="props.options[col.name]"
				/>
				
				<!-- Switch -->
				<SwitchField
					v-else-if="['Switch'].includes(col.controlType)" 
					:field="col"
					:data="formData"
				/>
                
                <!-- Cascader (替代TreeSelect) -->
<!--                <ElCascader
                  v-else-if="col.controlType === 'TreeSelect'"
                  v-model="formData[col.prop]"
                  :options="col.options || []"
                  :props="col.cascaderProps || { 
                    checkStrictly: true, 
                    emitPath: false,
                    label: 'label',
                    value: 'value',
                    children: 'children'
                  }"
                  :placeholder="col.placeholder || `请选择${col.label}`"
                  clearable
                  filterable
                  style="width: 100%"
                /> -->
                
                <!-- DatePicker -->
				<DatePickerField
					v-else-if="['DatePicker'].includes(col.controlType)" 
					:field="col"
					:data="formData"
				/>
				
				<!-- TimePicker -->
				<TimePickerField
					v-else-if="['TimePicker'].includes(col.controlType)" 
					:field="col"
					:data="formData"
				/>
				
				<!-- DateTimePickerField -->
				<DateTimePickerField
					v-else-if="['DateTimePickerField'].includes(col.controlType)" 
					:field="col"
					:data="formData"
				/>
                
                <!-- InputNumber -->
				<InputNumberField
					v-else-if="['InputNumber'].includes(col.controlType)" 
					:field="col"
					:data="formData"
				/>
				
				<!-- Slider -->
				<RateField
					v-else-if="['Rate'].includes(col.controlType)" 
					:field="col"
					:data="formData"
				/>
				
                <!-- Radio -->
				<RadioGroupField
					v-else-if="['Radio'].includes(col.controlType)" 
					:field="col"
					:data="formData"
				/>
				
                <!-- Checkbox -->
				<CheckboxGroupField
					v-else-if="['Checkbox'].includes(col.controlType)" 
					:field="col"
					:data="formData"
				/>
				<!-- ColorPickerField -->
 				<ColorPickerField
					v-else-if="['ColorPicker'].includes(col.controlType)" 
					:field="col"
					:data="formData"
				/> 
				</ElFormItem>
            </ElCol>
          </template>
        </ElRow>
      </template>
    </ElForm>
    
    <div class="preview-section" v-if="props.preview">
      <h3>表单数据预览</h3>
      <pre>{{ JSON.stringify(formData, null, 2) }}</pre>
    </div> 
  </div>
</template>

<script setup lang="ts">
import { 
  FormRules, 
  FormInstance, 
  FormItemRule,
  type ComponentSize 
} from 'element-plus'
import { ref, reactive, watch, computed, onMounted } from 'vue'
import { PropType } from 'vue-demi'
import { RuleService } from '@/api/data-rule/ruleApi'
import { DictService } from '@/api/sys/dictApi'
import InputField from './fields/InputField.vue'
import SelectField from './fields/SelectField.vue'
import TreeSelectField from './fields/TreeSelectField.vue'
import SwitchField from './fields/SwitchField.vue'
import RadioGroupField from './fields/RadioGroupField.vue'
import CheckboxGroupField from './fields/CheckboxGroupField.vue'
import InputNumberField from './fields/InputNumberField.vue'
import SliderField from './fields/SliderField.vue'
import RateField from './fields/RateField.vue'
import DatePickerField from './fields/DatePickerField.vue'
import TimePickerField from './fields/TimePickerField.vue'
import DateTimePickerField from './fields/DateTimePickerField.vue'
import ColorPickerField from './fields/ColorPickerField.vue'

// 定义 fetch 函数类型
type FetchFunction = (params?: any) => Promise<any>;

// 定义 fetchDatas 对象的结构
type FetchDataHandler = (
  value: any, 
  row: Record<string, any>, 
  fetchFunc: FetchFunction
) => any;

type FetchDatasType = Record<string, FetchDataHandler>;

const emit = defineEmits(['init:completed'])

const props = defineProps({
	rule: {
	  type: String,
	  default:"",
	  required: true
	},
	columnData: {
		type: Object as PropType<Record<string, any>>,
		default: () => ({})
	},
	fetchData: {
		type: Function as PropType<(params?: any) => Promise<any>>,
		required: false
	},
	autoLoad: {
		type: Boolean,
		default: true
	},
	data: {
		type: Object as PropType<Record<string, any>>,
		default: () => ({})
	},
	customFormatters: {
		type: Object as PropType<Record<string, (value: any, row: any) => any>>,
		default: () => ({})
	},
	fetchDatas: {
		type: Object as PropType<FetchDatasType>,
		default: () => ({}),
		validator: (value: FetchDatasType) => {
		  return Object.values(value).every(fn => typeof fn === 'function');
		}
	},
	options: {
		type: Object as PropType<Record<string, any>>,
		default: () => ({})
	},
	preview: {
		type: Boolean,
		default: false
	}
})

const formData = ref<Record<string, any>>({})
const fieldFormRef = ref<FormInstance>()
const columnConfigs = ref<any[]>([])
const loading = ref<boolean>(false)

// 计算分组后的行（每行最多24栅格）
const computedRows = computed(() => {
  const rows: any[][] = []
  let currentRow: any[] = []
  let currentSpan = 0

  for (const config of columnConfigs.value) {
    // 跳过不显示的字段
    if (!shouldShowField(config)) continue
    
    const span = config.span || 12
    
    // 如果当前配置需要独立成行
    if (span === 24) {
      if (currentRow.length > 0) {
        rows.push([...currentRow])
        currentRow = []
        currentSpan = 0
      }
      rows.push([config])
      continue
    }

    // 如果当前行放不下这个配置
    if (currentSpan + span > 24) {
      rows.push([...currentRow])
      currentRow = [config]
      currentSpan = span
    } else {
      currentRow.push(config)
      currentSpan += span
    }
  }

  // 添加最后一行
  if (currentRow.length > 0) {
    rows.push(currentRow)
  }

  return rows
})

// 检查字段是否应该显示
const shouldShowField = (col: any) => {
  return col.isVisible=='0'
}

// 初始化表单规则
const fieldRules = reactive<FormRules>({});

const initFormRules = () => {
  // 清空现有规则（保留响应性）
  Object.keys(fieldRules).forEach(key => delete fieldRules[key]);
  
  columnConfigs.value.forEach(config => {
    const rules: FormItemRule[] = [];
    
    // 1. 修复必填规则逻辑：isNullable='0' 表示必填
    if (config.isNullable === '1') {
      rules.push({
        required: true,
        message: `${config.label}不能为空`,
        trigger: ['blur', 'change']  // 同时支持失焦和值变化触发
      });
    }

    // 2. 添加长度验证
    if ((config.max != config.min) && ['Textarea','Input'].includes(config.controlType)) {
      rules.push({
        min: config.min ? Number(config.min) : 0,
        max: config.max ? Number(config.max) : undefined,
        message: `${config.label}长度需在${config.min || 0}-${config.max}之间`,
        trigger: 'blur'
      });
    }

    // 3. 添加正则表达式验证
    if (config.pattern) {
      rules.push({
        pattern: new RegExp(config.pattern),
        message: `${config.label}格式不正确`,
        trigger: 'blur'
      });
    }

    // 4. 添加自定义验证（示例）
    if (config.validator) {
      rules.push({
        validator: (_, value) => {
          // 这里可以接入外部验证函数
          if (typeof config.validator === 'function') {
            return config.validator(value);
          }
          return true;
        },
        trigger: 'blur'
      });
    }

    // 只有当存在规则时才添加
    if (rules.length > 0) {
      fieldRules[config.name] = rules;
    }
  });
};

// 初始化表单数据
const initFormData = () => {
  const initialData: Record<string, any> = {}
  for (const config of columnConfigs.value) {
    let defaultValue = undefined
	if(config.isArray=='1'){
		const values = new Set<any>([]) // 默认空值
		if (config.defaultValue && config.defaultValue !== undefined){
			config.defaultValue.split(',').forEach((item:any) => {
			  values.add(item.trim())
			})
		}
		defaultValue = Array.from(values)
	}else{
		defaultValue = config.defaultValue !== undefined ? config.defaultValue : undefined;
	}
    initialData[config.name] = defaultValue
  }
  
  // 合并传入的初始数据
  formData.value = { ...initialData, ...props.columnData }
}

const loadData = async (params?: any) => {
	if(props.fetchData){
		loading.value = true
		try {
		  // 使用props中的fetchData方法获取数据
		  const data = await props.fetchData(params)
		  if (data && data.length > 0) {
		    formData.value = { ...formData.value, ...data}
		  }
		} catch (error) {
		  console.error('数据加载失败', error)
		} finally {
		  loading.value = false
	}
  }
}

// API 请求封装
const fetchColumns = async () => {
  try {
    const { rule, fields } = await RuleService.getColumns(props.rule)
	columnConfigs.value=fields;
	initFormRules()
	initFormData();
	emit('init:completed',formData.value)
  } catch (error) {
    console.error('列配置加载失败', error)
  }
}

const getSelectOptions=async (code:string)=>{
	return await DictService.getSelectOptions(code);
}

// 暴露方法给父组件
defineExpose({
  validate: () => fieldFormRef.value?.validate(),
  getFormData: () => formData.value,
  resetForm: () => {
    if (fieldFormRef.value) {
      fieldFormRef.value.resetFields()
      initFormData()
    }
  },
  updateField: (prop: string, value: any) => {
    if (prop in formData.value) {
      formData.value[prop] = value
    }
  }
})

onMounted(async () => {
  await fetchColumns()
  if (props.autoLoad && props.fetchData!=null) {
    loadData()
  }else{
	  if(props.data){
		   formData.value = { ...formData.value, ...props.data } 
	  }
  }
})

// 监听外部传入的列数据变化
watch(() => props.columnData, (newVal) => {
  formData.value = { ...formData.value, ...newVal }
}, { deep: true })

// 监听外部传入的列数据变化
watch(() => props.data, (newVal) => {
  formData.value = { ...formData.value, ...newVal } 
}, { deep: true })

// 监听表单数据变化，处理条件字段
watch(formData, () => {
  // 当表单数据变化时，重新计算需要显示的字段
  // computedRows会自动更新
}, { deep: true })
</script>

<style scoped>
.dynamic-form-container {
  display: flex;
}

.dynamic-form {
  flex: 3;
}

.preview-section {
  flex: 2;
  padding: 25px;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.preview-section h3 {
  margin-top: 0;
  margin-bottom: 15px;
  color: #409eff;
  border-bottom: 1px solid #ebeef5;
  padding-bottom: 10px;
}

.preview-section pre {
  padding: 15px;
  border-radius: 6px;
  max-height: 500px;
  overflow: auto;
  font-size: 14px;
}

.el-col {
  margin-bottom: 0px;
}

.el-form-item {
  margin-bottom: 0px;
}

.el-row {
  margin-bottom: 18px;
}
</style>